home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 10 - 1994 / 10.07 Jul 94 / Programmers' Challenge / flip.c
Encoding:
Text File  |  1994-06-16  |  19.5 KB  |  606 lines  |  [TEXT/MSWD]

  1. // MacTech Magazine Programmers' Challenge
  2. // May, 1994
  3. // Submitted by Troy Anderson
  4. // 
  5. // Copyright (c) 1994 Troy L. Anderson
  6.  
  7. #include <QDOffscreen.h>
  8.  
  9. typedef unsigned char UCHAR;
  10.  
  11. // prototypes
  12. void FlipPixMapHorz( PixMapHandle thePixMapHndl);
  13.  
  14. static void Flip_Long(  PixMapHandle theMap, 
  15.                         short rowBytes,
  16.                         short depth,
  17.                         Rect* area);
  18.  
  19. static void Flip_Word(  PixMapHandle theMap, 
  20.                         short rowBytes,
  21.                         short depth,
  22.                         Rect* area);
  23.  
  24. static void ExchangeWords_Long( PixMapHandle theMap, 
  25.                                 short rowBytes,
  26.                                 short depth,
  27.                                 Rect* area);
  28.  
  29. static void ExchangeWords_Word( PixMapHandle theMap, 
  30.                                 short rowBytes,
  31.                                 short depth,
  32.                                 Rect* area);
  33.  
  34. static void ExchangeWords_Byte( PixMapHandle theMap, 
  35.                                 short rowBytes,
  36.                                 short depth,
  37.                                 Rect* area);
  38.  
  39.  
  40. // This could be made a bit faster by in-lining the 
  41. // functions, but this is much clearer, and not 
  42. // very much slower.
  43. void FlipPixMapHorz( PixMapHandle thePixMapHndl)
  44. {
  45.   short   rowBytes = (**thePixMapHndl).rowBytes & 0x7fff;
  46.   Boolean longAligned = rowBytes % 4 == 0;
  47.   short   depth = (**thePixMapHndl).pixelSize;
  48.   Rect    bounds = (**thePixMapHndl).bounds;
  49.   
  50.   switch( depth)
  51.   {
  52.     case  1:
  53.     case  2:
  54.     case  4:
  55.       if (longAligned)
  56.         Flip_Long(  thePixMapHndl, 
  57.                     rowBytes,
  58.                     depth,
  59.                     &bounds);
  60.       else
  61.         Flip_Word(  thePixMapHndl,
  62.                     rowBytes,
  63.                     depth,
  64.                     &bounds);
  65.       break;
  66.  
  67.     case  8:
  68.       ExchangeWords_Byte( thePixMapHndl,
  69.                           rowBytes,
  70.                           depth,
  71.                           &bounds);
  72.       break;
  73.     
  74.     case  16:
  75.       ExchangeWords_Word( thePixMapHndl,
  76.                           rowBytes,
  77.                           depth,
  78.                           &bounds);
  79.       break;
  80.       
  81.     case  32:
  82.       ExchangeWords_Long( thePixMapHndl,
  83.                           rowBytes,
  84.                           depth,
  85.                           &bounds);
  86.       break;
  87.   }
  88. }
  89.  
  90.  
  91.  
  92. // ExchangeWords - long word alignment version
  93. static void ExchangeWords_Long( PixMapHandle theMap,
  94.                                 short rowBytes,
  95.                                 short depth,
  96.                                 Rect* area)
  97. {
  98. #undef T
  99. #define T long
  100.  
  101.   short       rowCells = rowBytes / sizeof(T);
  102.   short       numCells = ((area->right - area->left) * 
  103.                       depth + sizeof(T)*8 - 1) / 
  104.                       (sizeof(T)*8);
  105.   T           temp;
  106.   register T  *cellPtr1, *cellPtr2;
  107.   T           *aRow;
  108.   T           *firstRow = (T*)GetPixBaseAddr( theMap);
  109.   T           *lastRow = firstRow + rowCells * 
  110.                         (long)(area->bottom - area->top);
  111.  
  112.     // Flip the words in each row
  113.   for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  114.     for ( cellPtr1 = aRow + numCells-1, cellPtr2 = aRow;
  115.         cellPtr1 > cellPtr2; 
  116.         cellPtr1--, cellPtr2++)
  117.       temp = *cellPtr1, // swap them 
  118.       *cellPtr1 = *cellPtr2, 
  119.       *cellPtr2 = temp;
  120. }
  121.  
  122.  
  123.  
  124. // ExchangeWords - word alignment version
  125. static void ExchangeWords_Word( PixMapHandle theMap,
  126.                                 short rowBytes,
  127.                                 short depth,
  128.                                 Rect* area)
  129. {
  130. #undef T
  131. #define T short
  132.  
  133.   short       rowCells = rowBytes / sizeof(T);
  134.   short       numCells = ((area->right - area->left) * 
  135.                       depth + sizeof(T)*8 - 1) / 
  136.                       (sizeof(T)*8);
  137.   T           temp;
  138.   register T  *cellPtr1, *cellPtr2;
  139.   T           *aRow;
  140.   T           *firstRow = (T*)GetPixBaseAddr( theMap);
  141.   T           *lastRow = firstRow + rowCells * 
  142.                         (long)(area->bottom - area->top);
  143.  
  144.     // Flip the words in each row
  145.   for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  146.     for ( cellPtr1 = aRow + numCells-1, cellPtr2 = aRow;
  147.         cellPtr1 > cellPtr2; 
  148.         cellPtr1--, cellPtr2++)
  149.       temp = *cellPtr1, // swap them 
  150.       *cellPtr1 = *cellPtr2, 
  151.       *cellPtr2 = temp;
  152. }
  153.  
  154.  
  155.  
  156. // ExchangeWords - byte alignment version
  157. static void ExchangeWords_Byte( PixMapHandle theMap,
  158.                                 short rowBytes,
  159.                                 short depth,
  160.                                 Rect* area)
  161. {
  162. #undef T
  163. #define T char
  164.  
  165.   short       rowCells = rowBytes / sizeof(T);
  166.   short       numCells = ((area->right - area->left) * 
  167.                       depth + sizeof(T)*8 - 1) / 
  168.                       (sizeof(T)*8);
  169.   T           temp;
  170.   register T  *cellPtr1, *cellPtr2;
  171.   T           *aRow;
  172.   T           *firstRow = (T*)GetPixBaseAddr( theMap);
  173.   T           *lastRow = firstRow + rowCells * 
  174.                         (long)(area->bottom - area->top);
  175.  
  176.     // Flip the words in each row
  177.   for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  178.     for ( cellPtr1 = aRow + numCells-1, cellPtr2 = aRow;
  179.         cellPtr1 > cellPtr2; 
  180.         cellPtr1--, cellPtr2++)
  181.       temp = *cellPtr1, // swap them 
  182.       *cellPtr1 = *cellPtr2, 
  183.       *cellPtr2 = temp;
  184. }
  185.  
  186.  
  187.  
  188. // Inverse tables used to flip the bits in a byte - 
  189. // index is input, value is inverse of index
  190.  
  191. // This is the 1-bit per pixel table
  192. static char byteFlips1[] ={ 
  193.   0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
  194.   0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  195.   0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
  196.   0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  197.   0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
  198.   0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
  199.   0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
  200.   0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
  201.   0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
  202.   0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
  203.   0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
  204.   0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
  205.   0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
  206.   0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
  207.   0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
  208.   0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
  209.   0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
  210.   0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
  211.   0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
  212.   0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
  213.   0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
  214.   0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
  215.   0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
  216.   0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  217.   0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
  218.   0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  219.   0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
  220.   0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
  221.   0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
  222.   0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
  223.   0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
  224.   0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff  };
  225.               
  226. // This is the 2-bits per pixel table
  227. static char byteFlips2[] ={ 
  228.   0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0, 
  229.   0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0,
  230.   0x04, 0x44, 0x84, 0xc4, 0x14, 0x54, 0x94, 0xd4, 
  231.   0x24, 0x64, 0xa4, 0xe4, 0x34, 0x74, 0xb4, 0xf4,
  232.   0x08, 0x48, 0x88, 0xc8, 0x18, 0x58, 0x98, 0xd8, 
  233.   0x28, 0x68, 0xa8, 0xe8, 0x38, 0x78, 0xb8, 0xf8, 
  234.   0x0c, 0x4c, 0x8c, 0xcc, 0x1c, 0x5c, 0x9c, 0xdc, 
  235.   0x2c, 0x6c, 0xac, 0xec, 0x3c, 0x7c, 0xbc, 0xfc, 
  236.   0x01, 0x41, 0x81, 0xc1, 0x11, 0x51, 0x91, 0xd1, 
  237.   0x21, 0x61, 0xa1, 0xe1, 0x31, 0x71, 0xb1, 0xf1, 
  238.   0x05, 0x45, 0x85, 0xc5, 0x15, 0x55, 0x95, 0xd5, 
  239.   0x25, 0x65, 0xa5, 0xe5, 0x35, 0x75, 0xb5, 0xf5, 
  240.   0x09, 0x49, 0x89, 0xc9, 0x19, 0x59, 0x99, 0xd9, 
  241.   0x29, 0x69, 0xa9, 0xe9, 0x39, 0x79, 0xb9, 0xf9, 
  242.   0x0d, 0x4d, 0x8d, 0xcd, 0x1d, 0x5d, 0x9d, 0xdd, 
  243.   0x2d, 0x6d, 0xad, 0xed, 0x3d, 0x7d, 0xbd, 0xfd, 
  244.   0x02, 0x42, 0x82, 0xc2, 0x12, 0x52, 0x92, 0xd2, 
  245.   0x22, 0x62, 0xa2, 0xe2, 0x32, 0x72, 0xb2, 0xf2, 
  246.   0x06, 0x46, 0x86, 0xc6, 0x16, 0x56, 0x96, 0xd6, 
  247.   0x26, 0x66, 0xa6, 0xe6, 0x36, 0x76, 0xb6, 0xf6, 
  248.   0x0a, 0x4a, 0x8a, 0xca, 0x1a, 0x5a, 0x9a, 0xda, 
  249.   0x2a, 0x6a, 0xaa, 0xea, 0x3a, 0x7a, 0xba, 0xfa, 
  250.   0x0e, 0x4e, 0x8e, 0xce, 0x1e, 0x5e, 0x9e, 0xde, 
  251.   0x2e, 0x6e, 0xae, 0xee, 0x3e, 0x7e, 0xbe, 0xfe, 
  252.   0x03, 0x43, 0x83, 0xc3, 0x13, 0x53, 0x93, 0xd3, 
  253.   0x23, 0x63, 0xa3, 0xe3, 0x33, 0x73, 0xb3, 0xf3, 
  254.   0x07, 0x47, 0x87, 0xc7, 0x17, 0x57, 0x97, 0xd7, 
  255.   0x27, 0x67, 0xa7, 0xe7, 0x37, 0x77, 0xb7, 0xf7, 
  256.   0x0b, 0x4b, 0x8b, 0xcb, 0x1b, 0x5b, 0x9b, 0xdb, 
  257.   0x2b, 0x6b, 0xab, 0xeb, 0x3b, 0x7b, 0xbb, 0xfb, 
  258.   0x0f, 0x4f, 0x8f, 0xcf, 0x1f, 0x5f, 0x9f, 0xdf, 
  259.   0x2f, 0x6f, 0xaf, 0xef, 0x3f, 0x7f, 0xbf, 0xff  };
  260.             
  261. // This is the 4-bits per pixel table
  262. static char byteFlips4[] ={ 
  263.   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 
  264.   0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
  265.   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 
  266.   0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1, 
  267.   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 
  268.   0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2, 
  269.   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 
  270.   0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3, 
  271.   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 
  272.   0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4, 
  273.   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 
  274.   0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, 
  275.   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 
  276.   0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, 
  277.   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 
  278.   0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, 
  279.   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 
  280.   0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, 
  281.   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 
  282.   0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9, 
  283.   0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, 
  284.   0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa, 
  285.   0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b, 
  286.   0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb, 
  287.   0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c, 
  288.   0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc, 
  289.   0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d, 
  290.   0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd, 
  291.   0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, 
  292.   0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe, 
  293.   0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 
  294.   0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff  };
  295.  
  296.  
  297.               
  298. static void Flip_Long(  PixMapHandle theMap, 
  299.                         short rowBytes,
  300.                         short depth,
  301.                         Rect* area)
  302. {
  303. #undef T
  304. #define T long
  305.  
  306.   register UCHAR  temp;
  307.   short           rowCells = rowBytes / sizeof(T);
  308.   long            bitsPerRow = (area->right - area->left) *
  309.                           (long)depth - 1;
  310.   short           numCells = (bitsPerRow + sizeof(T)*8) /
  311.                           (sizeof(T)*8);
  312.   T*              cellPtr;
  313.   T*              aRow;
  314.   T*              firstRow = (T*)GetPixBaseAddr( theMap);
  315.   T*              lastRow = firstRow + rowCells * 
  316.                       (long)(area->bottom - area->top);
  317.   
  318.   register T*     cellPtr1, *cellPtr2;
  319.  
  320.   short           numBitsToShift = ((sizeof(T)*8) -
  321.                       (bitsPerRow % (sizeof(T)*8) + 1));
  322.   T               shiftMask;
  323.   T*              shiftCellPtr;
  324.   char*           flipTable;
  325.   
  326.   
  327.  
  328.   switch(depth)
  329.   {
  330.     case 1:
  331.       flipTable = byteFlips1;
  332.       break;
  333.     case 2:
  334.       flipTable = byteFlips2;
  335.       break;
  336.     case 4:
  337.       flipTable = byteFlips4;
  338.       break;
  339.   }
  340.             
  341.  
  342.   if (numBitsToShift)
  343.   {
  344.     shiftMask = (1L << numBitsToShift) - 1;
  345.  
  346.     for ( aRow = firstRow; 
  347.         aRow < lastRow;
  348.         aRow += rowCells)
  349.     {
  350.       // With each pair of cells in the row 
  351.       // (one on the left, the other on the right),
  352.       // flip the pixels in the individual cells 
  353.       // and swap the cells with oneanother.
  354.       for ( cellPtr1 = aRow + numCells - 1, cellPtr2 = aRow;
  355.           cellPtr1 > cellPtr2;
  356.           cellPtr1--, cellPtr2++)
  357.       {
  358.         temp = ((UCHAR*)cellPtr1)[0];
  359.         ((UCHAR*)cellPtr1)[0] = 
  360.             flipTable[((UCHAR*)cellPtr2)[3]];
  361.         ((UCHAR*)cellPtr2)[3] = flipTable[temp];
  362.         
  363.         temp = ((UCHAR*)cellPtr1)[1];
  364.         ((UCHAR*)cellPtr1)[1] = 
  365.             flipTable[((UCHAR*)cellPtr2)[2]];
  366.         ((UCHAR*)cellPtr2)[2] = flipTable[temp];
  367.         
  368.         temp = ((UCHAR*)cellPtr1)[2];
  369.         ((UCHAR*)cellPtr1)[2] = 
  370.             flipTable[((UCHAR*)cellPtr2)[1]];
  371.         ((UCHAR*)cellPtr2)[1] = flipTable[temp];
  372.         
  373.         temp = ((UCHAR*)cellPtr1)[3];
  374.         ((UCHAR*)cellPtr1)[3] = 
  375.             flipTable[((UCHAR*)cellPtr2)[0]];
  376.         ((UCHAR*)cellPtr2)[0] = flipTable[temp];
  377.       }
  378.       
  379.       // If there's an odd number of cells in the row, 
  380.       // there is one cell we haven't touched. 
  381.       // It needs to be flipped.
  382.       if (cellPtr1 == cellPtr2)
  383.       {
  384.         temp = ((UCHAR*)cellPtr1)[0];
  385.         ((UCHAR*)cellPtr1)[0] = 
  386.             flipTable[((UCHAR*)cellPtr1)[3]];
  387.         ((UCHAR*)cellPtr1)[3] = flipTable[temp];
  388.         
  389.         temp = ((UCHAR*)cellPtr1)[1];
  390.         ((UCHAR*)cellPtr1)[1] = 
  391.             flipTable[((UCHAR*)cellPtr1)[2]];
  392.         ((UCHAR*)cellPtr1)[2] = flipTable[temp];
  393.       }
  394.  
  395.       // Slide the pixels to the left
  396.       for ( shiftCellPtr = aRow;
  397.           shiftCellPtr < aRow + rowCells;
  398.           shiftCellPtr++)
  399.       {
  400.         // shift the bits over
  401.         *shiftCellPtr <<= numBitsToShift;
  402.           
  403.         // bring in the bits from the next cell - 
  404.         // garbage will be brought in during last 
  405.         // iteration, but its put into the last
  406.         // cell, outside the bounds of the image
  407.         // (but still in the data area)
  408.         *shiftCellPtr |= shiftMask & 
  409.                         (*(shiftCellPtr+1) >> 
  410.                           (sizeof(T)*8 - numBitsToShift));
  411.       }
  412.     }
  413.   }
  414.   else  // no need to shift pixels, otherwise, 
  415.   {     // just the same as previous loop
  416.     for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  417.     {
  418.       // With each pair of cells in the row (one on the 
  419.       // left, the other on the right), flip the pixels
  420.       // in the individual cells and swap the cells with
  421.       // one another.
  422.       for ( cellPtr1 = aRow + numCells - 1, cellPtr2 = aRow;
  423.             cellPtr1 > cellPtr2;
  424.             cellPtr1--, cellPtr2++)
  425.       {
  426.         temp = ((UCHAR*)cellPtr1)[0];
  427.         ((UCHAR*)cellPtr1)[0] =
  428.             flipTable[((UCHAR*)cellPtr2)[3]];
  429.         ((UCHAR*)cellPtr2)[3] = flipTable[temp];
  430.         
  431.         temp = ((UCHAR*)cellPtr1)[1];
  432.         ((UCHAR*)cellPtr1)[1] = 
  433.             flipTable[((UCHAR*)cellPtr2)[2]];
  434.         ((UCHAR*)cellPtr2)[2] = flipTable[temp];
  435.         
  436.         temp = ((UCHAR*)cellPtr1)[2];
  437.         ((UCHAR*)cellPtr1)[2] = 
  438.             flipTable[((UCHAR*)cellPtr2)[1]];
  439.         ((UCHAR*)cellPtr2)[1] = flipTable[temp];
  440.         
  441.         temp = ((UCHAR*)cellPtr1)[3];
  442.         ((UCHAR*)cellPtr1)[3] = 
  443.             flipTable[((UCHAR*)cellPtr2)[0]];
  444.         ((UCHAR*)cellPtr2)[0] = flipTable[temp];
  445.       }
  446.       
  447.       // If there are an odd number of cells in the row,
  448.       // there is one cell we haven't touched.
  449.       // It needs to be flipped.
  450.       if (cellPtr1 == cellPtr2)
  451.       {
  452.         temp = ((UCHAR*)cellPtr1)[0];
  453.         ((UCHAR*)cellPtr1)[0] = 
  454.             flipTable[((UCHAR*)cellPtr1)[3]];
  455.         ((UCHAR*)cellPtr1)[3] = flipTable[temp];
  456.         
  457.         temp = ((UCHAR*)cellPtr1)[1];
  458.         ((UCHAR*)cellPtr1)[1] = 
  459.             flipTable[((UCHAR*)cellPtr1)[2]];
  460.         ((UCHAR*)cellPtr1)[2] = flipTable[temp];
  461.       }
  462.     }
  463.   }
  464. }
  465.  
  466.  
  467.  
  468.  
  469.  
  470. static void Flip_Word(  PixMapHandle theMap, 
  471.                         short rowBytes,
  472.                         short depth,
  473.                         Rect* area)
  474. {
  475. #undef T
  476. #define T short
  477.  
  478.   register UCHAR  temp;
  479.   short           rowCells = rowBytes / sizeof(T);
  480.   long            bitsPerRow = (area->right - area->left) *
  481.                           (long)depth - 1;
  482.   short           numCells = (bitsPerRow + sizeof(T)*8) /
  483.                           (sizeof(T)*8);
  484.   T*              cellPtr;
  485.   T*              aRow;
  486.   T*              firstRow = (T*)GetPixBaseAddr( theMap);
  487.   T*              lastRow = firstRow + rowCells * 
  488.                       (long)(area->bottom - area->top);
  489.   
  490.   register T*     cellPtr1, *cellPtr2;
  491.  
  492.   short           numBitsToShift = ((sizeof(T)*8) -
  493.                       (bitsPerRow % (sizeof(T)*8) + 1));
  494.   T               shiftMask;
  495.   T*              shiftCellPtr;
  496.   char*           flipTable;
  497.   
  498.   
  499.  
  500.   switch(depth)
  501.   {
  502.     case 1:
  503.       flipTable = byteFlips1;
  504.       break;
  505.     case 2:
  506.       flipTable = byteFlips2;
  507.       break;
  508.     case 4:
  509.       flipTable = byteFlips4;
  510.       break;
  511.   }
  512.             
  513.  
  514.   if (numBitsToShift)
  515.   {
  516.     shiftMask = (1L << numBitsToShift) - 1;
  517.  
  518.     for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  519.     {
  520.       // With each pair of cells in the row 
  521.       // (one on the left, the other on the right),
  522.       // flip the pixels in the individual cells 
  523.       // and swap the cells with oneanother.
  524.       for ( cellPtr1 = aRow + numCells - 1, cellPtr2 = aRow;
  525.           cellPtr1 > cellPtr2;
  526.           cellPtr1--, cellPtr2++)
  527.       {
  528.         temp = ((UCHAR*)cellPtr1)[0];
  529.         ((UCHAR*)cellPtr1)[0] = 
  530.             flipTable[((UCHAR*)cellPtr2)[1]];
  531.         ((UCHAR*)cellPtr2)[1] = flipTable[temp];
  532.         
  533.         temp = ((UCHAR*)cellPtr1)[1];
  534.         ((UCHAR*)cellPtr1)[1] =
  535.             flipTable[((UCHAR*)cellPtr2)[0]];
  536.         ((UCHAR*)cellPtr2)[0] = flipTable[temp];
  537.       }
  538.       
  539.       // If there's an odd number of cells in the row, 
  540.       // there is one cell we haven't touched. 
  541.       // It needs to be flipped.
  542.       if (cellPtr1 == cellPtr2)
  543.       {
  544.         temp = ((UCHAR*)cellPtr1)[0];
  545.         ((UCHAR*)cellPtr1)[0] = 
  546.             flipTable[((UCHAR*)cellPtr1)[1]];
  547.         ((UCHAR*)cellPtr1)[1] = 
  548.             flipTable[temp];
  549.       }
  550.  
  551.       // Slide the pixels to the left
  552.       for ( shiftCellPtr = aRow;
  553.           shiftCellPtr < aRow + rowCells;
  554.           shiftCellPtr++)
  555.       {
  556.       // shift the bits over
  557.         *shiftCellPtr <<= numBitsToShift;
  558.           
  559.       // bring in the bits from the next cell - 
  560.       // garbage will be brought in during last 
  561.       // iteration, but its put into the last
  562.       // cell, outside the bounds of the image
  563.       // (but still in the data area)
  564.         *shiftCellPtr |= shiftMask & 
  565.                         (*(shiftCellPtr+1) >> 
  566.                           (sizeof(T)*8 - numBitsToShift));
  567.       }
  568.     }
  569.   }
  570.   else  // no need to shift pixels, otherwise, 
  571.   {     // just the same as previous loop
  572.     for ( aRow = firstRow; aRow < lastRow; aRow += rowCells)
  573.     {
  574.       // With each pair of cells in the row (one on the 
  575.       // left, the other on the right), flip the pixels
  576.       // in the individual cells and swap the cells with
  577.       // one another.
  578.       for ( cellPtr1 = aRow + numCells - 1, cellPtr2 = aRow;
  579.             cellPtr1 > cellPtr2;
  580.             cellPtr1--, cellPtr2++)
  581.       {
  582.         temp = ((UCHAR*)cellPtr1)[0];
  583.         ((UCHAR*)cellPtr1)[0] = 
  584.             flipTable[((UCHAR*)cellPtr2)[1]];
  585.         ((UCHAR*)cellPtr2)[1] = flipTable[temp];
  586.         
  587.         temp = ((UCHAR*)cellPtr1)[1];
  588.         ((UCHAR*)cellPtr1)[1] = 
  589.             flipTable[((UCHAR*)cellPtr2)[0]];
  590.         ((UCHAR*)cellPtr2)[0] = flipTable[temp];
  591.       }
  592.       
  593.       // If there are an odd number of cells in the row,
  594.       // there is one cell we haven't touched.
  595.       // It needs to be flipped.
  596.       if (cellPtr1 == cellPtr2)
  597.       {
  598.         temp = ((UCHAR*)cellPtr1)[0];
  599.         ((UCHAR*)cellPtr1)[0] = 
  600.             flipTable[((UCHAR*)cellPtr1)[1]];
  601.         ((UCHAR*)cellPtr1)[1] = flipTable[temp];
  602.       }
  603.     }
  604.   }
  605. }
  606.